package com.jokerpan.project.service.impl;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.jokerpan.project.commons.ActionResult;
import com.jokerpan.project.commons.PaginationBuilder;
import com.jokerpan.project.commons.ResultBuilder;
import com.jokerpan.project.entity.BackFiles;
import com.jokerpan.project.entity.BlogAction;
import com.jokerpan.project.entity.Blogs;
import com.jokerpan.project.entity.Users;
import com.jokerpan.project.mapper.BackFilesMapper;
import com.jokerpan.project.mapper.BlogActionMapper;
import com.jokerpan.project.mapper.BlogsMapper;
import com.jokerpan.project.mapper.CommentMapper;
import com.jokerpan.project.service.BackFilesService;
import com.jokerpan.project.service.BlogsService;
import com.jokerpan.project.service.MinIoService;
import com.jokerpan.project.util.UserTool;
import com.vdurmont.emoji.EmojiParser;
import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @author jokerpan
 */
@Service("blogsService")
public class BlogsServiceImpl implements BlogsService {
    @Resource
    BlogsMapper blogsMapper;
    @Resource
    MinIoService minIoService;
    @Resource
    BackFilesMapper backFilesMapper;
    @Resource
    BackFilesService backFilesService;
    @Resource
    CommentMapper commentMapper;
    @Resource
    UserTool userTool;
    @Resource
    BlogActionMapper blogActionMapper;


    @Override
    public Map<String, Object> queryList(Blogs blogs) {
        Page<Object> page = PageHelper.startPage(blogs.getCurrentPage(), blogs.getPageSize());
        List<Blogs> resultList = this.blogsMapper.queryList(blogs);
        return PaginationBuilder.buildResult(resultList, page.getTotal(), blogs.getCurrentPage(), blogs.getPageSize());
    }

    @Override
    public List<Blogs> queryByUserId(Blogs blogs) {
        return this.blogsMapper.queryByUserId(blogs);
    }

    @Override
    public Blogs queryById(Integer id) {
        return this.blogsMapper.queryById(id);
    }

    /**
     * 处理博客内容中的图片
     * @param htmlStr
     * @param blogs
     * @return
     */
    public String dealImgStr(String htmlStr, Blogs blogs) {
        String result = htmlStr;
        String img = "";
        Pattern p_image;
        Matcher m_image;
        //     String regEx_img = "<img.*src=(.*?)[^>]*?>"; //图片链接地址
        String regEx_img = "<img.*src\\s*=\\s*(.*?)[^>]*?>";
        p_image = Pattern.compile(regEx_img, Pattern.CASE_INSENSITIVE);
        m_image = p_image.matcher(htmlStr);
        while (m_image.find()) {
            // 得到<img />数据
            img = m_image.group();
            // 匹配<img>中的src数据
            Matcher m = Pattern.compile("src\\s*=\\s*\"?(.*?)(\"|>|\\s+)").matcher(img);
            while (m.find()) {
                String oldPath = m.group(1);
                String newPath = minIoService.copyFile("BLOG", blogs.getId(), oldPath);
                if (!newPath.equals("error")){
                    backFilesMapper.deleteByUrl(oldPath);
                    BackFiles backFiles = new BackFiles();
                    backFiles.setSource("Blog");
                    backFiles.setPk(blogs.getId());
                    backFiles.setUrl(newPath);
                    backFilesService.add(backFiles);
                    result = result.replace(oldPath, newPath);
                }else {
                    return null;
                }
            }
        }
        return result;
    }

    /**
     * 获取字符串中img图片地址
     * @param htmlStr
     * @return
     */
    public List<String> getImgSrc(String htmlStr) {
        if( htmlStr == null ){
            return null;
        }
        List<String> list = new ArrayList<>();
        String img = "";
        Pattern p_image;
        Matcher m_image;
        String regEx_img = "<img.*src\\s*=\\s*(.*?)[^>]*?>";
        p_image = Pattern.compile(regEx_img, Pattern.CASE_INSENSITIVE);
        m_image = p_image.matcher(htmlStr);
        while (m_image.find()) {
            img = m_image.group();
            Matcher m = Pattern.compile("src\\s*=\\s*\"?(.*?)(\"|>|\\s+)").matcher(img);
            while (m.find()) {
                list.add(m.group(1));
            }
        }
        return list;
    }

    @Override
    public Blogs add(Blogs blogs) {
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        blogs.setCreateTime(format.format(new Date()));
        //将表情转换为字符
        blogs.setContent(EmojiParser.parseToAliases(blogs.getContent()));
        try {
            blogsMapper.add(blogs);
        }catch (Exception e){
            return null;
        }
        Blogs blogs1 = blogsMapper.queryMaxId();
        String newPath = "";
        if (StringUtils.isNotBlank(blogs.getCover())){
            newPath = minIoService.copyFile("BLOG", blogs1.getId(), blogs.getCover());
            if (newPath.equals("error")) {
                return null;
            }
            backFilesMapper.deleteByUrl(blogs.getCover());
            BackFiles backFiles = new BackFiles();
            backFiles.setSource("Blog");
            backFiles.setPk(blogs1.getId());
            backFiles.setUrl(newPath);
            backFilesService.add(backFiles);
        }
        //处理博客内容中的img链接
        String content = dealImgStr(blogs1.getContent(), blogs1);
        if (content == null){
            return null;
        }
        blogs1.setContent(content);
        blogs1.setCover(newPath);
        blogsMapper.update(blogs1);
        blogs1 = blogsMapper.queryById(blogs1.getId());
        return blogs1;
    }

    @Override
    public ActionResult update(Blogs blogs) {
        String action = blogs.getAction();
        if (action != null){
            SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            Users users = userTool.getCurrentUser();
            Blogs blog = blogsMapper.queryById(blogs.getId());
            BlogAction blogAction = new BlogAction();
            blogAction.setUserId(users.getId());
            blogAction.setObjId(blog.getId());
            blogAction.setActionTime(format.format(new Date()));
            List<BlogAction> blogActionList;
            if (action.equals("like")){
                blogAction.setActionType("blog_like");
                blogActionList = blogActionMapper.queryList(blogAction);
                blogs.setLikeCount((blog.getLikeCount() != null ? blog.getLikeCount() : 0) + 1);
                if (blogActionList.size() > 0){
                    return ResultBuilder.buildActionFailed("oi！不能重复点赞哦");
                }
            }else if(action.equals("star")){
                blogAction.setActionType("blog_star");
                blogActionList = blogActionMapper.queryList(blogAction);
                blogs.setStarCount((blog.getStarCount() != null ? blog.getStarCount() : 0) + 1);
                if (blogActionList.size() > 0){
                    return ResultBuilder.buildActionFailed("oi！不能重复收藏哦");
                }
            }else if(action.equals("view")){
                blogAction.setActionType("blog_view");
            }
            blogActionMapper.add(blogAction);
        }
        if (blogsMapper.update(blogs) > 0){
            return ResultBuilder.buildActionSuccess();
        }else {
            return ResultBuilder.buildActionFailed();
        }
    }

    @Override
    public ActionResult deleteById(Integer id) {
        Blogs blogs = blogsMapper.queryById(id);
        //删除封面文件
        minIoService.deleteFile(blogs.getCover());
        backFilesMapper.deleteByUrl(blogs.getCover());
        //删除content中的图片文件
        List<String> imgList = getImgSrc(blogs.getContent());
        if (imgList != null && imgList.size() > 0){
            imgList.forEach(e -> {
                minIoService.deleteFile(e);
                backFilesMapper.deleteByUrl(e);
            });
        }
        //删除此博客下的所有评论
        commentMapper.deleteByBlogId(id);
        //删除此博客的所有点赞、收藏数据
        blogActionMapper.deleteByObjId(id);
        blogsMapper.deleteById(id);
        return ResultBuilder.buildActionSuccess();
    }
}
